package utils

import (
	"math"
	log "misc/seelog"
	"os"
)

func CheckError(err error) {
	if err != nil {
		log.Info(err)
		os.Exit(-1)
	}
}

type Action func(...interface{})
type Action0 func()
type Action1 func(interface{})
type Action2 func(interface{}, interface{})
type Action3 func(interface{}, interface{}, interface{})
type Action4 func(interface{}, interface{}, interface{}, interface{})

type Func func(...interface{}) interface{}
type Func0 func() interface{}
type Func1 func(interface{}) interface{}
type Func2 func(interface{}, interface{}) interface{}
type Func3 func(interface{}, interface{}, interface{}) interface{}
type Func4 func(interface{}, interface{}, interface{}, interface{}) interface{}

type Ray struct {
	Origin *Vec3
	Dir    *Vec3
}

type Pane struct {
	Normal *Vec3
	Pos    *Vec3
}

func NewPanelByNormal(poinA *Vec3, normal *Vec3) *Pane {
	retPanel := &Pane{Pos: poinA, Normal: normal}
	return retPanel
}

type Segment struct {
	PointA *Vec2
	PointB *Vec2
}

type Line struct {
	PointA *Vec3
	PointB *Vec3
}

func determinant(v1, v2, v3, v4 float64) float64 {
	return v1*v3 - v2*v4
}

func between(a, X0, X1 float64) bool {
	temp1 := a - X0
	temp2 := a - X1
	if (temp1 < (1e-8) && temp2 > -(1e-8)) || (temp2 < (1e-6) && temp1 > -(1e-8)) {
		return true
	} else {
		return false
	}
}

func (this *Segment) Intersect(other *Segment) (b bool, lineX, lineY float64) {
	//var lineX, lineY float64
	lineX = 0
	lineY = 0
	if math.Abs(this.PointA.X-this.PointB.X) < (1e-6) && math.Abs(other.PointA.X-other.PointB.X) < (1e-6) {
		b = false
		return
	} else if math.Abs(this.PointA.X-this.PointB.X) < (1e-6) { //如果直线段p1p2垂直与y轴
		if between(this.PointA.X, other.PointA.X, other.PointB.X) {
			k := (other.PointB.Y - other.PointA.Y) / (other.PointB.X - other.PointA.X)
			lineX = this.PointA.X
			lineY = k*(lineX-other.PointA.X) + other.PointA.Y
			if between(lineY, this.PointA.Y, this.PointB.Y) {
				b = true
				return
			} else {
				b = false
				return
			}
		}
	} else if math.Abs(other.PointA.X-other.PointB.X) < (1e-6) { //如果直线段p3p4垂直与y轴
		if between(other.PointA.X, this.PointA.X, this.PointB.X) {
			k := (this.PointB.Y - this.PointA.Y) / (this.PointB.X - this.PointA.X)
			lineX = other.PointA.X
			lineY = k*(lineX-this.PointB.X) + this.PointB.Y
			if between(lineY, other.PointA.Y, other.PointB.Y) {
				b = true
				return
			} else {
				b = false
				return
			}
		} else {
			b = false
			return
		}
	} else {
		k1 := (this.PointB.Y - this.PointA.Y) / (this.PointB.X - this.PointA.X)
		k2 := (other.PointB.Y - other.PointA.Y) / (other.PointB.X - other.PointA.X)
		if math.Abs(k1-k2) < (1e-6) {
			b = false
			return
		} else {
			lineX = ((other.PointA.Y - this.PointA.Y) - (k2*other.PointA.X - k1*this.PointA.X)) / (k1 - k2)
			lineY = k1*(lineX-this.PointA.X) + this.PointA.Y
		}
		if between(lineX, this.PointA.X, this.PointB.X) && between(lineX, other.PointA.X, other.PointB.X) {
			b = true
			return
		} else {
			b = false
			return
		}
	}
	b = false
	return
}
